<?php  
/**
 * ****************************************************************************
 * php5 lib v1.0 for xiaoeni api 
 * @author alex.wu  contact email: wuhata@hotmail.com
 *    
 * discuss group in xiaonei http://group.xiaonei.com/GetTribe.do?id=250895852
 * document url:  http://apps.xiaonei.com/geoblogs/bloguid.php?uid=1000008&catid=1000004&catname=PHP%E5%BC%80%E5%8F%91
 */

include "xiaonei.class.php";
class Xiaonei {
  	public $api_client;
  	public $api_key;
  	public $secret;
  	public $generate_session_secret;
  	public $session_expires;
  	public $fb_params;
  	public $user; 	  	
    public function __construct($api_key, $secret, $generate_session_secret=false) {
   	 //header('P3P: CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV"');//
  
    $this->api_key                 = $api_key;
    $this->secret                  = $secret;
    $this->generate_session_secret = $generate_session_secret;
    $this->api_client = new XiaoneiRestClient($api_key, $secret);    
    $this->validate_fb_params();      
    if (isset($this->fb_params['added'])) {
        $this->api_client->added = $this->fb_params['added'];
    }       
    //print_r($_COOKIE);
    //exit();
  }  
       
  public function validate_fb_params($resolve_auth_token=true) {
    $this->fb_params = $this->get_valid_fb_params($_POST, 480*3600, 'yk_sig');
    if (count($this->fb_params)<=0) {
      $this->fb_params = $this->get_valid_fb_params($_GET, 480*3600, 'yk_sig');
    }
  
    if (count($this->fb_params)>0) {
      // If we got any fb_params passed in at all, then either:
      //  - they included an fb_user / fb_session_key, which we should assume to be correct
      //  - they didn't include an fb_user / fb_session_key, which means the user doesn't have a
      //    valid session and if we want to get one we'll need to use require_login().  (Calling
      //    set_user with null values for user/session_key will work properly.)
      // Note that we should *not* use our cookies in this scenario, since they may be referring to
      // the wrong user.      
      $user        = isset($this->fb_params['user'])        ? $this->fb_params['user'] : null;
      $session_key = isset($this->fb_params['session_key']) ? $this->fb_params['session_key'] : null;
      $expires     = isset($this->fb_params['expires'])     ? $this->fb_params['expires'] : null;
      $this->set_user($user, $session_key, $expires);
    } else if (!empty($_COOKIE) && $cookies = $this->get_valid_fb_params($_COOKIE, null, $this->api_key)) {
      // use $api_key . '_' as a prefix for the cookies in case there are
      // multiple facebook clients on the same domain.
      $expires = isset($cookies['expires']) ? $cookies['expires'] : null;
      $this->fb_params=$cookies;
      $this->set_user($cookies['user'], $cookies['session_key'], $expires);
    }
    return !empty($this->fb_params);
  }

  public function redirect($url) {
    if ($this->in_fb_canvas()) {
      echo '<xn:redirect url="' . $url . '"/>';
    } else if (preg_match('/^http?:\/\/([^\/]*\.)?xiaonei\.com(:\d+)?/i', $url)) {
      // make sure facebook.com url's load in the full frame so that we don't
      // get a frame within a frame.
      echo "<script type=\"text/javascript\">\ntop.location.href = \"$url\";\n</script>";
    } else {
      header('Location: ' . $url);
    }
    exit;
  }
   
  public static function current_url() {
    return 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
  } 
    
  public static function get_xiaonei_url($subdomain='www') {
       return 'http://' . $subdomain . '.xiaonei.com';
  }
  
  public function get_install_url($next=null) {
    // this was renamed, keeping for compatibility's sake
    return $this->get_add_url($next);
  }  
    
  public function get_add_url($invite_id=null) {      
     return self::get_xiaonei_url("app")."/apps/install.do?api_key=".$this->api_key."&invite_id=".$invite_id;
  }       
  
  public function get_login_url($next, $canvas) {
  	 if($canvas)
  	   return self::get_xiaonei_url("login")."/Login.do?rf=r&origURL=".urlencode($next);
  	 else 
  	   return self::get_xiaonei_url("login")."/Login.do";  
  }    
    
  public function get_loggedin_user() {
    return $this->user;
  }

  public static function generate_sig($params_array, $secret) {
    $str = '';
    ksort($params_array);
    // Note: make sure that the signature parameter is not already included in
    //       $params_array.
    foreach ($params_array as $k=>$v) {
      $str .= "$k=$v";
    }
    $str .= $secret;
    return md5($str);
  }    
   public function require_login() {
   	//print_r($this);
   	$user = $this->get_loggedin_user();
   	//echo "user=$user";
    if (intval($user)>0) {
         return $user;
    }    
    $this->redirect($this->get_login_url(self::current_url(), $this->in_frame()));
  }

  public function require_install() {
    // this was renamed, keeping for compatibility's sake
    return $this->require_add();
  }
  
  public function require_add() {
    if ($user = $this->get_loggedin_user()) {
    	return $user;
      if ($this->fb_params['added']) {
        
      }
    }
    $this->redirect($this->get_add_url(self::current_url()));
  }

  
  public function require_frame() {
    if (!$this->in_frame()) {
      $this->redirect($this->get_login_url(self::current_url(), true));
    }
  }
       
  public function set_user($user, $session_key, $expires=null, $session_secret=null) {
    if (!$this->in_fb_canvas() && (!isset($_COOKIE[$this->api_key . '_user'])
                                   || $_COOKIE[$this->api_key . '_user'] != $user)) {
      $this->set_cookies($user, $session_key, $expires, $session_secret);
    }       
    $this->user = $user;
    $this->api_client->session_key = $session_key;
    $this->session_expires = $expires;
  }
  
  public function in_frame() {
    return isset($this->fb_params['in_iframe']);
  } 
  
  public function in_fb_canvas() {
    return isset($this->fb_params['in_canvas']);
  }  
  public function set_cookies($user, $session_key, $expires=null, $session_secret=null) {
    $cookies = array();
    $cookies['user'] = $user;
    $cookies['session_key'] = $session_key;
    $cookies['added']=1;
/*
    if ($expires != null) {
      $cookies['expires'] = $expires;
    }
    if ($session_secret != null) {
      $cookies['ss'] = $session_secret;
    }    
    foreach ($cookies as $name => $val) {
      setcookie($this->api_key . '_' . $name, $val,null,"/");
      //echo "set cookie $name=$val\r\n";
      $_COOKIE[$this->api_key . '_' . $name] = $val;
    }    
    $sig = self::generate_sig($cookies, $this->secret);
    setcookie($this->api_key, $sig,null,"/");
     //echo "set cookie sig=$sig\r\n";
    $_COOKIE[$this->api_key] = $sig;
    */
   }
  /**
   * Tries to undo the badness of magic quotes as best we can
   * @param     string   $val   Should come directly from $_GET, $_POST, etc.
   * @return    string   val without added slashes
   */
  public static function no_magic_quotes($val) {
    if (get_magic_quotes_gpc()) {
      return stripslashes($val);
    } else {
      return $val;
    }
  }
   
  public function get_valid_fb_params($params, $timeout=null, $namespace='yk_sig') {
    $prefix = $namespace . '_';
    $prefix_len = strlen($prefix);
    $fb_params = array();
    foreach ($params as $name => $val) {
      if (strpos($name, $prefix) === 0) {
        $fb_params[substr($name, $prefix_len)] = self::no_magic_quotes($val);
      }
    }        
    if ($timeout && (!isset($fb_params['time']) || time() - $fb_params['time'] > $timeout)) {
        //return array();
    }              
   if(isset($fb_params[$namespace])){
    if(!$this->verify_signature($fb_params, $params[$namespace]))
    	 return array();  	
    	
   }
   return $fb_params;   
    
  }
    


  // Invalidate the session currently being used, and clear any state associated with it
  public function expire_session() {
  	
      if (!$this->in_fb_canvas() && isset($_COOKIE[$this->api_key . '_user'])) {
        $cookies = array('user', 'session_key', 'expires', 'ss');
        foreach ($cookies as $name) {
          setcookie($this->api_key . '_' . $name, false, time() - 3600);
          unset($_COOKIE[$this->api_key . '_' . $name]);
        }
        setcookie($this->api_key, false, time() - 3600);
        unset($_COOKIE[$this->api_key]);
      }
      // now, clear the rest of the stored state
      $this->user = 0;
      $this->api_client->session_key = 0;
      return true;
    
  } 
  
  public function verify_signature($fb_params, $expected_sig) {
    return self::generate_sig($fb_params, $this->secret) == $expected_sig;
  }
  
  
}
  
  
?>